package cn.nexttec.noteplayer.common

import android.content.Context
import android.os.Build
import android.os.Environment
import android.os.storage.StorageManager
import cn.nexttec.noteplayer.models.VideoFileInfo
import java.io.File

const val TAG = "NotePlayerApp"

/**
 * 获取可移动 SD 卡的根目录（兼容 Android 11 ~ 14）
 */
fun Context.getAppRootOfSdCardRemovable(): ArrayList<String>? {
    if (Environment.getExternalStorageState() != Environment.MEDIA_MOUNTED) return null

    val paths = ArrayList<String>()
    val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager

    try {
        val storageVolumeClazz = Class.forName("android.os.storage.StorageVolume")
        val getVolumeList = storageManager.javaClass.getMethod("getVolumeList")
        val volumeList = getVolumeList.invoke(storageManager)
        val length = java.lang.reflect.Array.getLength(volumeList)

        // 反射方法（兼容老版本）
        val getPath = storageVolumeClazz.methods.find { it.name == "getPath" }
        val getDirectory = storageVolumeClazz.methods.find { it.name == "getDirectory" }
        val isRemovable = storageVolumeClazz.getMethod("isRemovable")

        for (i in 0 until length) {
            val volume = java.lang.reflect.Array.get(volumeList, i)
            val removable = isRemovable.invoke(volume) as? Boolean ?: false
            if (!removable) continue

            val path = when {
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && getDirectory != null -> {
                    val file = getDirectory.invoke(volume) as? File
                    file?.absolutePath
                }

                getPath != null -> {
                    getPath.invoke(volume) as? String
                }

                else -> null
            }

            if (!path.isNullOrEmpty()) {
                paths.add(path)
                TAG debug path
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
        TAG debug e.stackTraceToString()
    }

    return if (paths.isNotEmpty()) paths else null
}

fun walk(path: String, depth: Int = 0, onVideosFound: (List<VideoFileInfo>) -> Unit) {
    val TAG = "FileScanService"
    val dirPath = File(path)
    var files = dirPath.listFiles()?.toList()
    if (files.isNullOrEmpty()) {
        TAG debug "$path: files is NullOrEmpty"
        return
    }
    files = files.filter { it.name != "Android" }

    TAG debug "$path: found files: ${files.joinToString { it.name }}"

    if (files.map { it.name }.any { it == ".nomedia" }) {
        TAG debug "$path: contain .nomedia"
        return
    }

    val videoFiles = files.filter { it.isVideoFile() }
    if (videoFiles.isNotEmpty()) {
        videoFiles.forEach {
            TAG debug it.absolutePath
        }

        onVideosFound(videoFiles.map {
            VideoFileInfo.fromVideoFile(it, depth)
        })

        onVideosFound(
            listOf(
                VideoFileInfo.fromDirectory(
                    dirPath, depth, "${videoFiles.size}个视频"
                )
            )
        )
    }
    val directories = files.filter { it.isDirectory }
    directories.filter { it.name[0] != '.' }.forEach {
        TAG debug it.absolutePath
        walk(it.absolutePath, depth + 1, onVideosFound)
    }

}

fun File.isVideoFile(): Boolean {
    return isFile && (name.endsWith(".mp4") || name.endsWith("mkv") || name.endsWith(".avi"))
}


